/* See COPYRIGHT for copyright information. */

#include <inc/mmu.h>
#include <inc/memlayout.h>
#include <inc/trap.h>

#include <kern/picirq.h>


###################################################################
# exceptions/interrupts
###################################################################

/* The TRAPHANDLER macro defines a globally-visible function for handling
 * a trap.  It pushes a trap number onto the stack, then jumps to _alltraps.
 * Use TRAPHANDLER for traps where the CPU automatically pushes an error code.
 */ 
#define TRAPHANDLER(name, num)						\
.text;									\
	.globl name;		/* define global symbol for 'name' */	\
	.type name, @function;	/* symbol type is function */		\
	.align 2;		/* align function definition */		\
	name:			/* function starts here */		\
	pushl $(num);							\
	jmp _alltraps;							\
.data; 	/*table*/							\
	.long num;							\
	.long name
/* Use TRAPHANDLER_NOEC for traps where the CPU doesn't push an error code.
 * It pushes a 0 in place of the error code, so the trap frame has the same
 * format in either case.
 */
#define TRAPHANDLER_NOEC(name, num)					\
.text;									\
	.globl name;							\
	.type name, @function;						\
	.align 2;							\
	name:								\
	pushl $0;							\
	pushl $(num);							\
	jmp _alltraps;							\
.data; 	/*table*/							\
	.long num;							\
	.long name

/*
 * Lab 3: Your code here for generating entry points for the different traps.
 */
.data
.globl idttab
idttab:
TRAPHANDLER_NOEC(div_fault,T_DIVIDE)
TRAPHANDLER_NOEC(debug_trap,T_DIVIDE)
TRAPHANDLER_NOEC(nmi_inter,T_NMI)
TRAPHANDLER_NOEC(brk_int,T_BRKPT)
TRAPHANDLER_NOEC(oflow_int,T_OFLOW)
TRAPHANDLER(trap_dblfault,T_DBLFLT) /*09*/
TRAPHANDLER(bad_tss,T_TSS) /*10*/
TRAPHANDLER(bad_seg,T_SEGNP)  /**/
TRAPHANDLER(stack_fault,T_STACK)  /**/
TRAPHANDLER(gpf_fault,T_GPFLT)  /**/
TRAPHANDLER(page_fault,T_PGFLT)  /*14*/
TRAPHANDLER_NOEC(sys_call,T_SYSCALL) ; /*48*/
.data
	.long 0x0 
	.long 0x0 
/*
 * Lab 3: Your code here for _alltraps
 */
.text
_alltraps:
	push %ds	
	push %es
	pushal 
	movw $GD_KD, %ax
	movw %ax, %ds
	movw %ax, %es
	push %esp
	call trap	
	pop %esp	
	popal
	pop %es	
	pop %ds
	iret
